<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script type="text/javaScript">
    // 箭头函数使用示例
    let arr = [1, 2, 3]
    // filter 过滤
    let arr1 = arr.filter(item => item === 2)
    console.log(arr)
    console.log(arr1)
    // map 对数组整体进行操作
    let arr2 = arr.map(item => item * 2)
    console.log(arr)
    console.log(arr2)
    // reduce 累加
    let arr3 = arr.reduce((acc, cur) => acc + cur)
    console.log(arr)
    console.log(arr3)

    let iterator = arr[Symbol.iterator]() // 需要用健名形式访问 Symbol.iterator
    iterator.next() // {value: 1, done: false}
    iterator.next() // {value: 2, done: false}
    iterator.next() // {value: 3, done: false}
    iterator.next() // {value: undefined, done: true}

    let arr = [1, 2, 3, 4, 5]
    let arr2 = [...arr, 6, 7, 8] // 1 2 3 4 5 6 7 8

    let [first, ...arr] = [1, 2, 3 ,4 ,5]
    // first = 1  arr = [2, 3, 4, 5]

    // 在对象中使用扩展运算符 (es9 语法)
    let obj = {
      a: 1,
      b: 2,
      c: 3
    }
    let obj2 = {
      ...obj,
      d: 4
    }
    // obj2 = {a:1, b:2, c:3, d:4}
    // 跟 Object.assign 相似， Object.assign会触发目标对象的 setter 函数，而对象扩展运算符不会。
    
    // 对象 属性/方法 简写
    let x = 0
    let obj = {
      x // es6允许省略x:
    }
    // 省略的是属性名而不是值
    // 值必须是一个变量

    // 对象的属性简写经常与结构赋值一起使用
    let bar = () => ({x:4, y:5, z:6})

    let {x:x, y:y, z:z} = bar()
    // 简写为
    let {x, y, z} = bar()

    // 方法的简写
    // es5
    let obj = {
      func: function () {

      }
    }
    // es6 简写
    let obj2 = {
      func () {

      }
    }
    // 箭头函数写法
    let obj3 = {
      func: () => {

      }
    }

    // for...in  for...of
    // 1. for...of 遍历获取的是对象的键值，for...in获取的是对象的键名
    // 2. for...in 会遍历整个原型链, 性能非常差不推荐使用, 而for...of只遍历当前对象不会遍历原型链

    // 模块化
    // 导出 module.js
    let x = 10
    let y = 20
    export {x}
    export default y
    // 导入
    import {x} from "./module.js"
    import y from "./module.js"

    // 这两者的区别是
    // export {<变量>} 导出的是一个变量的引用
    // exprot default 导出的是一个值
    // a.js 使用 import 导入这两个变量后
    // 在module.js x 改变后 会立刻反应到 a.js, y 改变后 a.js 的 y 还是原来的值
    
    // 实例
    // module.js
    let x = 10
    let y = 20
    setTimeout(() => {
      x = 100
      y = 200
    }, 1000);
    export {x}
    export default y
    // a.js
    import {x} from "./module.js"
    import y from "./module.js"
    console.log(x, y)
    setTimeout(() => {
      console.log(x, y) // 100  20
    }, 1000)

    // 函数默认值
    // es5
    function func (a) {
      return a || 1
    }
    func() // 1
    // es6
    function func (a = 1) {
      return a
    }
    func() // 1
  </script>
</body>
</html>